/*
 *  Copyright (C) 2008      Tri Tech Information Systems Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */


#include <boost/python.hpp>

#include "rpp/pp.h"


using namespace boost::python;

struct Preprocessor
{
    rpp::pp_environment m_env;
    std::vector< std::string > m_paths;

    void init_pp( rpp::pp& proc )
    {
        for( std::vector<std::string>::iterator it = m_paths.begin();
                it != m_paths.end(); ++it )
            proc.push_include_path( *it );
    }

    std::string processFile( const std::string& file )
    {
        rpp::pp proc( m_env );
        init_pp( proc );

        std::string result;
        result.reserve( 20480 );    // 20K
        proc.file( file, std::back_inserter(result) );

        return result;
    }

    std::string processString( const std::string& str )
    {
        rpp::pp proc( m_env );
        init_pp( proc );

        std::string result;
        proc( str.begin(), str.end(), std::back_inserter(result) );

        return result;
    }

    void addIncludePath( const std::string& path )
    {
        m_paths.push_back( path );
    }
};


void Wrap_Preprocessor()
{
    class_< Preprocessor >( "Preprocessor" )
        .def( "processFile", &Preprocessor::processFile )
        .def( "processString", &Preprocessor::processString )
        .def( "addIncludePath", &Preprocessor::addIncludePath )
        ;
}
